use crate::common::AppState;
use crate::error::AppError;
use crate::models::user::User;
use axum::extract::{Request, State};
use axum::middleware::Next;
use axum::response::IntoResponse;
use http::{header, StatusCode};
use std::collections::HashMap;
use std::sync::Arc;
// use axum_extra::headers::Authorization;
// use axum_extra::headers::authorization::Bearer;
// use axum_extra::TypedHeader;
use tokio::time::Instant;
// use validator::ValidateRequired;

pub async fn auth_middleware(
    State(state): State<Arc<AppState>>,
    mut req: Request,
    next: Next,
) -> impl IntoResponse {
    //
    //
    // let (mut parts,body) = req.into_parts();
    // return match TypedHeader::<Authorization<Bearer>>::from_request_parts(&mut parts, &state).await {
    //     Ok(TypedHeader(Authorization(token))) => {
    //         let token = token.token();
    //         match state.dk.verify(token) {
    //             Ok(user) => {
    //                 req.extensions_mut().insert(user);
    //                 next.run(Request::from_parts(parts, body)).await
    //             }
    //             Err(e) => {
    //                 (StatusCode::UNAUTHORIZED, "Invalid token").into_response()
    //             }
    //         }
    //     },
    //     Err(e) => {
    //         (StatusCode::UNAUTHORIZED, "Invalid token").into_response()
    //     }
    // };

    // 如果请求路径是 /api/register 或 /api/sign，则直接放行
    if req.uri().path() == "/api/register" || req.uri().path() == "/api/sign" {
        println!("{:?}", req.headers());
        return next.run(req).await;
    }
    let token: Option<&str>;
    let query_params: HashMap<String, String>;

    if req.uri().path() == "/events" {
        let query = req.uri().query().unwrap_or_default();
        // 将查询字符串解析为键值对
        query_params = form_urlencoded::parse(query.as_bytes())
            .into_owned()
            .collect();
        token = query_params
            .get("access_token")
            .and_then(|value| value.strip_prefix("Bearer "));
    } else {
        // 获取请求头
        // 从请求中提取令牌
        token = req
            .headers()
            .get(header::AUTHORIZATION)
            .and_then(|value| value.to_str().ok())
            .and_then(|value| value.strip_prefix("Bearer "));
    }

    // 验证令牌
    match token {
        Some(token) => match validate_token(token, state.clone()) {
            Ok(user) => {
                let state = state.clone();
                let _ = state.user.lock().unwrap().insert(user.clone());
                req.extensions_mut().insert(user);
                let start = Instant::now();
                let res = next.run(req).await;
                let end = Instant::now();
                println!("Time elapsed: {:?}", end.duration_since(start));
                res
            }
            Err(_e) => (StatusCode::UNAUTHORIZED, "Invalid token").into_response(),
        },
        _ => {
            // 返回未授权错误
            (StatusCode::UNAUTHORIZED, "Invalid token").into_response()
        }
    }
}

fn validate_token(token: &str, state: Arc<AppState>) -> Result<User, AppError> {
    state.dk.verify(token)
}
